﻿using System;
using System.Collections.Generic;
using System.Net;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System.IO;
using System.Text;

namespace Net.Formats.oEmbed
{
    
    
    /// <summary>
    ///This is a test class for RequestTest and is intended
    ///to contain all RequestTest Unit Tests
    ///</summary>
    [TestClass( )]
    public class RequestTest
    {
        private TestContext testContextInstance;

        #region Test Page Content
        private string mockContent = @"<html>
<head>
<title>oEmbed</title>
<link rel=""alternate"" type=""application/json+oembed""
	href=""http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=json""
	title=""Bacon Lollys oEmbed Profile"" />
<link rel=""alternate"" type=""text/xml+oembed""
	href=""http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=xml""
	title=""Bacon Lollys oEmbed Profile"" />
<style>
body, input, textarea, select {
	font-family: Arial,Helvetica,sans-serif;
	padding: 20px 50px;
}
pre {
	background-color: #eee;
	border: 1px solid #999;
	padding: 8px;
	margin: 0px 20px;
}
code {
	background-color: #eee;
	border: 1px solid #999;
	padding: 0px 2px;
}
</style>
</head>
<body>
<h1>oEmbed</h1>
<p>oEmbed is a format for allowing an embedded representation of a URL on third party sites. The simple API allows a website to display embedded content (such as photos or videos) when a user posts a link to that resource, without having to parse the resource directly.</p>
<h2>1. Quick Example</h2>
<p>A <i>consumer</i> (eg. <a href=""http://pownce.com/"">Pownce</a>) makes the following HTTP request:</p>
<ul>
	<li> <code>http://www.flickr.com/services/oembed/?url=http%3A//www.flickr.com/photos/bees/2341623661/</code> </li>
</ul>
<p>The <i>provider</i> (eg. <a href=""http://www.flickr.com/"">Flickr</a>) then responds with an oEmbed response:</p>
<p>This allows the consumer to turn a URL to a Flickr photo page into structured data to allow embedding of that photo in the consumer's website.</p>
<h2>2. Full Spec</h2>
<p>This spec is broken into three parts - configuration, the consumer request and the provider response.</p>
</body>
</html>";

        #endregion

        #region JSON Response Content

        string jsonResponseContent = @"{
	""version"": ""1.0"",
	""type"": ""video"",
	""provider_name"": ""YouTube"",
	""provider_url"": ""http://youtube.com/"",
	""width"": 425,
	""height"": 344,
	""title"": ""Amazing Nintendo Facts"",
	""author_name"": ""ZackScott"",
	""author_url"": ""http://www.youtube.com/user/ZackScott"",
	""html"":
		""<object width=\""425\"" height=\""344\"">
			<param name=\""movie\"" value=\""http://www.youtube.com/v/M3r2XDceM6A&fs=1\""></param>
			<param name=\""allowFullScreen\"" value=\""true\""></param>
			<param name=\""allowscriptaccess\"" value=\""always\""></param>
			<embed src=\""http://www.youtube.com/v/M3r2XDceM6A&fs=1\""
				type=\""application/x-shockwave-flash\"" width=\""425\"" height=\""344\""
				allowscriptaccess=\""always\"" allowfullscreen=\""true\""></embed>
		</object>""}";

        #endregion

        #region XML Response Content

        string xmlResponseContent = @"<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?>
<oembed>
	<version>1.0</version>
	<type>link</type>
	<author_name>Cal Henderson</author_name>
	<author_url>http://iamcal.com/</author_url>
	<cache_age>86400</cache_age>
	<provider_name>iamcal.com</provider_name>
	<provider_url>http://iamcal.com/</provider_url>
</oembed>";

        #endregion

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion     

        [TestMethod()]
        public void DiscoverProviderEndpointXmlFormatTest( )
        {
            var requestParams = new RequestParameters
            {
                ResourceUrl = new Uri( "http://testurl/resource.html" )
            };

            string expected = @"http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=xml";
            var mockLoader = new Mock<IResourceLoader>( );
            mockLoader.Setup( m => m.GetResourceContent( requestParams.ResourceUrl ) ).Returns( mockContent );

            var request = new Request( requestParams, mockLoader.Object );
            
            Assert.IsNotNull( request.oEmbedResourceUrl );
            Assert.AreEqual( expected, request.oEmbedResourceUrl.AbsoluteUri );
        }

        [TestMethod( )]
        public void DiscoverProviderEndpointJSONFormatTest( )
        {
            var requestParams = new RequestParameters
            {
                ResourceUrl = new Uri( "http://testurl/resource.html" ),
                Format = ResponseFormat.JSON
            };

            string expected = @"http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=json";
            var mockLoader = new Mock<IResourceLoader>( );
            mockLoader.Setup( m => m.GetResourceContent( requestParams.ResourceUrl ) ).Returns( mockContent );

            var request = new Request(requestParams, mockLoader.Object );           

            Assert.IsNotNull( request.oEmbedResourceUrl );

            Assert.AreEqual( expected, request.oEmbedResourceUrl.AbsoluteUri );
        }

        [TestMethod( )]
        public void DiscoverProviderEndpointNullFormatTest( )
        {
            var requestParams = new RequestParameters
            {
                ResourceUrl = new Uri( "http://testurl/resource.html" )
            };

            string expected = @"http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=xml";
            var mockLoader = new Mock<IResourceLoader>( );
            mockLoader.Setup( m => m.GetResourceContent( requestParams.ResourceUrl ) ).Returns( mockContent );

            var request = new Request( requestParams, mockLoader.Object);
            
            Assert.IsNotNull( request.oEmbedResourceUrl );
            Assert.AreEqual( expected, request.oEmbedResourceUrl.AbsoluteUri );
        }

        [TestMethod( )]
        public void RequestResourceAsJSONTest( )
        {
            var url = new Uri( "http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=json" );

            ResponseFormat format = ResponseFormat.JSON;

            var mock = new Mock<IResourceLoader>( );
            mock.Setup( m => m.GetResourceType( url, out format ) ).Returns( jsonResponseContent );

            var request = new Request( url, mock.Object );
            VideoResponse response = request.CreateResponse( ) as VideoResponse;

            Assert.IsNotNull( response );
            Assert.AreEqual( "1.0", response.Version );
            Assert.AreEqual( "video", response.Type.ToString( ).ToLower() );
            Assert.AreEqual( "YouTube", response.ProviderName );
            Assert.AreEqual( "http://youtube.com/", response.ProviderUrl.AbsoluteUri );
            Assert.AreEqual( 425, response.Width );
            Assert.AreEqual( 344, response.Height );
            Assert.AreEqual( "Amazing Nintendo Facts", response.Title );
            Assert.AreEqual( "ZackScott", response.AuthorName );
            Assert.AreEqual( "http://www.youtube.com/user/ZackScott", response.AuthorUrl.AbsoluteUri );
            Assert.AreEqual( @"<object width=""425"" height=""344"">
			<param name=""movie"" value=""http://www.youtube.com/v/M3r2XDceM6A&fs=1""></param>
			<param name=""allowFullScreen"" value=""true""></param>
			<param name=""allowscriptaccess"" value=""always""></param>
			<embed src=""http://www.youtube.com/v/M3r2XDceM6A&fs=1""
				type=""application/x-shockwave-flash"" width=""425"" height=""344""
				allowscriptaccess=""always"" allowfullscreen=""true""></embed>
		</object>", response.Html );

        }

        [TestMethod]
        public void RequestResourceAsXMLTest( )
        {
            var url = new Uri( "http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=json" );

            ResponseFormat format = ResponseFormat.XML;
            
            var mock = new Mock<IResourceLoader>( );
            mock.Setup( m => m.GetResourceType( url, out format ) ).Returns( xmlResponseContent );

            var request = new Request( url, mock.Object );
            var response = request.CreateResponse<LinkResponse>( );

            Assert.IsNotNull( response );
            Assert.AreEqual( "1.0", response.Version );
            Assert.AreEqual( "link", response.Type.ToString().ToLower() );
            Assert.AreEqual( "Cal Henderson",response.AuthorName );
            Assert.AreEqual( "http://iamcal.com/", response.AuthorUrl.AbsoluteUri );
            Assert.AreEqual( 86400, response.CacheAge );
            Assert.AreEqual( "iamcal.com", response.ProviderName );
            Assert.AreEqual( "http://iamcal.com/", response.ProviderUrl.AbsoluteUri );
        }
        
    }
}
